<?php
namespace yiike\core\components;

use Yii;
use yii\db\Migration;

/**
 * 扩展模块迁移基类
 * Class ModuleMigration
 * @package yiike\core\components
 */
class ModuleMigration extends Migration
{
    public $routes;
    
    public $menus;
    
    /**
     * @var yiike\core\models\Module
     */
    public $module;

    final public function up()
    {
        $transaction = $this->db->beginTransaction();
        try {
            if ($this->install() === false) {
                $transaction->rollBack();

                return false;
            }
            $transaction->commit();
        } catch (\Exception $e) {
            Yii::warning("Exception: " . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")", __METHOD__);

            $transaction->rollBack();

            return false;
        }

        return null;
    }

    final public function safeDown()
    {
        $transaction = $this->db->beginTransaction();
        try {
            if ($this->uninstall() === false) {
                $transaction->rollBack();

                return false;
            }
            $transaction->commit();
        } catch (\Exception $e) {
            Yii::warning("Exception: " . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")", __METHOD__);

            $transaction->rollBack();

            return false;
        }

        return null;
    }

    /**
     * 升级到指定版本
     */
    final public function to($fromVersion, $toVersion)
    {
        $transaction = $this->db->beginTransaction();
        try {
            if ($this->upgrade($fromVersion, $toVersion) === false) {
                $transaction->rollBack();

                return false;
            }
            $transaction->commit();
        } catch (\Exception $e) {
            Yii::warning("Exception: " . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")", __METHOD__);
            $transaction->rollBack();

            return false;
        }

        return null;
    }

    /**
     * 扩展模块被安装时会执行此函数
     * @return mixed
     */
    public function install()
    {
    }

    /**
     * 扩展模块被卸载时会执行此函数
     * @return mixed
     */
    public function uninstall()
    {
    }

    /**
     * 扩展模块被升级时会执行此函数
     * @return mixed
     */
    public function ungrade($fromVersion, $toVersion)
    {
    }

    /**
     * 判断表是否存在(预防表数据安装失败)
     * @param $tableName
     * @return bool
     */
    public function tableExists($tableName)
    {
        return $this->db->schema->getTableSchema($tableName, true) !== null;
    }
    
    function addRoute($routes)
    {
        $manager = Yii::$app->getAuthManager();
        foreach ($routes as $route) {
            try {
                $r = explode('&', $route);
                $item = $manager->createPermission('/' . trim($route, '/'));
                if (count($r) > 1) {
                    $action = '/' . trim($r[0], '/');
                    if (($itemAction = $manager->getPermission($action)) === null) {
                        $itemAction = $manager->createPermission($action);
                        $manager->add($itemAction);
                    }
                    unset($r[0]);
                    foreach ($r as $part) {
                        $part = explode('=', $part);
                        $item->data['params'][$part[0]] = isset($part[1]) ? $part[1] : '';
                    }
                    $this->setDefaultRule();
                    $item->ruleName = RouteRule::RULE_NAME;
                    $manager->add($item);
                    $manager->addChild($item, $itemAction);
                } else {
                    $manager->add($item);
                }
            } catch (Exception $e) {

            }
        }
    }
    function removeRoute($routes) {        
        $manager = Yii::$app->getAuthManager();
        foreach ($routes as $route) {
            $child = $manager->getPermission($route);
            if (! $child) continue;
            try {
                $manager->remove($child);
            } catch (Exception $exc) {
                $error[] = $exc->getMessage();
            }
        }
    }

    function updateRole($id, $action, $roles) {
        $manager = Yii::$app->getAuthManager();
        $parent = $manager->getRole($id);
        $error = [];
        if ($action == 'assign') {
            foreach ($roles as $role) {
                $child = $manager->getRole($role);
                $child = $child ? : $manager->getPermission($role);
                try {
                    $manager->addChild($parent, $child);
                } catch (\Exception $e) {
                    $error[] = $e->getMessage();
                }
            }
        } else {
            foreach ($roles as $role) {
                $child = $manager->getRole($role);
                $child = $child ? : $manager->getPermission($role);
                if (! $child) continue;
                try {
                    $manager->removeChild($parent, $child);
                } catch (\Exception $e) {
                    $error[] = $e->getMessage();
                }
            }
        }
    }
}